package com.bone.modules.system.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.bone.common.constant.Dict;
import com.bone.common.util.BoneUtils;
import com.bone.common.util.JwtUtil;
import com.bone.common.util.RedisUtils;
import com.bone.common.vo.Result;
import com.bone.modules.system.dto.UserLoginDto;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.beans.factory.annotation.Autowired;
import com.bone.modules.system.service.ISysUserService;
import com.bone.modules.system.entity.SysUser;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;

import java.util.Arrays;

import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletResponse;

/**
 * 用户表 前端控制器
 *
 * @author : 王可可
 * @date : 2020-12-07
 */
@Api(tags = "用户管理")
@RestController
@RequestMapping("/system/sysUser")
public class SysUserController {

    @Autowired
    private ISysUserService sysUserService;

    @Autowired
    private RedisUtils redisUtil;


    @ApiOperation("用户-账号登录")
    @PostMapping("/login")
    public Result<String> sysLogin(@RequestBody @Validated UserLoginDto userLoginDto,
                                   HttpServletResponse response) {
        SysUser user = sysUserService.getOne(new LambdaQueryWrapper<SysUser>()
                .eq(SysUser::getUsername, userLoginDto.getUsername()));
        if (BoneUtils.isEmpty(user)) {
            return Result.error("当前用户不存在");
        }
        // 将当前输入密码 MD5加盐 加密
        String md5Password = BoneUtils.encrypt(userLoginDto.getUsername(), userLoginDto.getPassword(), user.getSalt());
        if (!md5Password.equals(user.getPassword())) {
            return Result.error("密码错误！");
        }
        // 获取当前时间戳
        String currentTimeMillis = String.valueOf(System.currentTimeMillis());
        // 创建/覆盖 该用户ID所对应的refresh_token信息 生命周期为60min
        redisUtil.set(Dict.PREFIX_SHIRO_REFRESH_TOKEN + user.getId(), currentTimeMillis, Dict.REFRESH_TOKEN_TIME);
        // 创建token (时间戳、和refresh_token一样的时间戳，过期时间戳)
        String token = JwtUtil.sign(user.getId().toString(), md5Password, currentTimeMillis);
        // 将token放入 返回头的X_ACCESS_TOKEN中
        response.setHeader(Dict.X_ACCESS_TOKEN, token);
        response.setHeader("Access-Control-Expose-Headers", Dict.X_ACCESS_TOKEN);
        return Result.ok("登录成功");
    }

    @ApiOperation("用户-账号注册")
    @PostMapping("/register")
    public Result<String> sysRegister(@RequestBody @Validated UserLoginDto userLoginDto) {
        // 由于字段做了后端验证所以这里无需判空
        SysUser sysUser = sysUserService.getOne(new LambdaQueryWrapper<SysUser>()
                .eq(SysUser::getUsername, userLoginDto.getUsername()));
        if (BoneUtils.isNotEmpty(sysUser)) {
            return Result.error("该用户名已被注册");
        }
        return sysUserService.accountRegister(userLoginDto) ? Result.ok("注册成功") : Result.error("注册失败");
    }

    @ApiOperation("用户-账号退出")
    @DeleteMapping("/logout")
    public Result<String> umsUserLogout() {
        Subject subject = SecurityUtils.getSubject();
        SysUser sysUser = (SysUser) subject.getPrincipal();
        String refreshTokenKey = Dict.PREFIX_SHIRO_REFRESH_TOKEN + sysUser.getId();
        redisUtil.del(refreshTokenKey);
        subject.logout();
        return Result.ok("退出成功");
    }

    @ApiOperation("用户-登录信息")
    @GetMapping("/info")
    public Result<SysUser> userResult() {
        // 在认证的时候，已经将用户信息存入Subject中 故可以通过其获取当前用户信息
        Subject subject = SecurityUtils.getSubject();
        return Result.ok((SysUser) subject.getPrincipal());
    }


    /**
     * 查询分页数据
     */
    @ApiOperation(value = "查询分页数据")
    @GetMapping(value = "/page")
    public Result<Page<SysUser>> findListByPage(@RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
                                                @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize) {
        return Result.ok(sysUserService.page(new Page<>(pageNo, pageSize)));
    }

    /**
     * 根据id查询
     */
    @ApiOperation(value = "根据id查询数据")
    @GetMapping(value = "/getById")
    public Result<SysUser> getById(@RequestParam("id") String id) {
        return Result.ok(sysUserService.getById(id));
    }

    /**
     * 新增
     */
    @ApiOperation(value = "新增数据")
    @PostMapping(value = "/add")
    public Result<SysUser> add(@RequestBody SysUser sysUser) {
        return sysUserService.save(sysUser) ? Result.ok() : Result.error("添加失败");
    }

    /**
     * 删除
     */
    @ApiOperation(value = "删除数据")
    @DeleteMapping(value = "/del")
    public Result<String> delete(@RequestParam("ids") String ids) {
        return sysUserService.removeByIds(Arrays.asList(ids.split(","))) ? Result.ok() : Result.error("删除失败");
    }

    /**
     * 修改
     */
    @ApiOperation(value = "更新数据")
    @PutMapping(value = "/update")
    public Result<SysUser> update(@RequestBody SysUser sysUser) {
        return sysUserService.updateById(sysUser) ? Result.ok() : Result.error("更新失败");
    }

}
